#ifndef	__BASECODEPAGEENCODING_H__
#define	__BASECODEPAGEENCODING_H__

namespace BFX
{

/////////////////////////////////////////////////////////////////////////////

class REFBaseCodePageEncoding : public REFEncoding
{
	friend class REFEncoding;
protected:
	const static BYTE	s_pCodePagesData[];

	//
	// Inner classes/structures
	//

	// Specifies packing alignment to 2 bytes
#pragma pack(push, 2)

	struct CodePageIndex
	{
		// Offset(0)
		UCHAR CodePageName[16];		// WORD[16]
		// Offset(0x20)
		INT16 CodePage;				// WORD
		// Offset(0x22)
		INT16 ByteCount;			// WORD
		// Offset(0x24)
		INT32 Offset;				// DWORD
	};

	// This is the header for the native data table that we load from CodePages.
	struct CodePageDataFileHeader
	{
		// Offset(0)
		UCHAR	TableName[16];		// WORD[16]
		// Offset(0x20)
		UINT16	Version[4];			// WORD[4]
		// Offset(0x28)
		INT16	CodePageCount;		// WORD
		// Offset(0x2A)
		INT16	unused1;			// Add a unused WORD so that CodePages is aligned with DWORD boundary.
		// Otherwise, 64-bit version will fail.
		// Offset(0x2C)
		CodePageIndex	CodePages;	// Start of code page index
	};

	struct CodePageHeader
	{
		// Offset(0)
		UCHAR	CodePageName[16];	// WORD[16]
		// Offset(0x20)
		UINT16	VersionMajor;		// WORD
		// Offset(0x22)
		UINT16	VersionMinor;		// WORD
		// Offset(0x24)
		UINT16	VersionRevision;	// WORD
		// Offset(0x26)
		UINT16	VersionBuild;		// WORD
		// Offset(0x28)
		INT16	CodePage;			// WORD
		// Offset(0x2a)
		INT16	ByteCount;			// WORD     // 1 or 2 byte code page (SBCS or DBCS)
		// Offset(0x2c)
		UCHAR	UnicodeReplace;		// WORD     // default replacement unicode character
		// Offset(0x2e)
		UINT16	ByteReplace;		// WORD     // default replacement bytes
		// Offset(0x30)
		INT16	FirstDataWord;		// WORD[]
	};

	// Restore packing alignment
#pragma pack(pop)

	//
	// Constructors
	//
protected:
	REFBaseCodePageEncoding(int nPageCode, int nDataCodePage);
	virtual ~REFBaseCodePageEncoding();

	//
	// Overrides
	//

	// We have a managed code page entry, so load our tables
	virtual void LoadManagedCodePage()	= 0;

	//
	// Methods
	//
protected:
	// Allocate memory to load our code page
	BYTE* GetSharedMemory(int iSize);

	// Detect the memory section handle then re-initialize the memory section if necessay.
	void CheckMemorySection() const;

	// Get our code page byte count
	static int GetCodePageByteSize(int nCodePage);

private:
	// We need to load tables for our code page
	void LoadCodePageTables();

	// Look up the code page pointer
	static const CodePageHeader* FindCodePage(int nCodePage);

	//
	// Attributes
	//
protected:
	const CodePageHeader*	m_pCodePage;

	int		m_nDataTableCodePage;

	// section map view base address
	BYTE*	m_pMemorySection;
};

}	//	namespace BFX

#endif	//	__BASECODEPAGEENCODING_H__

